#include "../Web_Search/WebPageSearcher.h"
#include "SingleMap.h"
#include "Thread.h"
#include "KeyRecommander.h"
#include "MyTask.h"
#include <iostream>
#include <sw/redis++/redis.h>

using std::cout;
using std::endl;
using namespace sw::redis;

WordSegmentation *SingleCut::_wordSeg = getInstance();
std::mutex SingleCut::_mutex;
keyWordCommander* singleKeyCom::_keyW=getInstance();
std::mutex singleKeyCom::_mutex;
LRUcache *singleLRU::_LRUcache=getInstance();
std::mutex singleLRU::_mutex;
MyMap *SingleMap::_mm = getInstance();
std::mutex SingleMap::_mutex;


MyTask::MyTask(const TcpConnectionPtr &con, const pair<int, string> msgParse)
: _con(con)
, _msg(msgParse){}


// 将处理好的 msg 发送给 TcpConnection, 通过 TcpConnection 返回给客户端
void MyTask::process(void* mode, LRUmanager &m){
    /* cout << "   >>Sub thread " << name << " get the task!" << endl; */
    LogInfo("Sub thread %s get the task!", name);
    if(_msg.first == 1){ // 关键字查询
        handleMsgKey(mode, m); 
    } 
    else{ // 网页查询
        handleMsgWeb(mode); 
    }
    _con->sendInLoop(queryResult);
}



void MyTask::handleMsgKey(void* mode, LRUmanager &m){
    vector<string>* vec = static_cast<KeyRecommander*>(mode)->getQueryKeyPtr(); 
    // 查 LRU 
    LRUcache* lc = singleLRU::getInstance();

    // -------------------------------------------------- 
    // 老版本, 可以正常跑通  
    // LRUcache lrc(*lc);
    // *vec = lrc.LRUsearch(_msg.second); 
    // -------------------------------------------------- 

    // -------------------------------------------------- 
    // 新版本 
    LRUcache& cache = (m.getCaches())[atoi(name)];
    cache = *lc;
    *vec = cache.LRUsearch(_msg.second); 
    // -------------------------------------------------- 

    if(vec->size()!=0){
        cout << "---------LRU----------" << endl;
        LogInfo("LRU");
        queryResult.first=1;
        queryResult.second = static_cast<void*>(vec);
    }
    else{
        static_cast<KeyRecommander*>(mode)->doQuery(_msg.second);  
        queryResult.first = 1; 
        queryResult.second = static_cast<void*>(static_cast<KeyRecommander*>(mode)->getQueryKeyPtr()); 
    }
}



void MyTask::handleMsgWeb(void *mode){
    MyMap *mmp = SingleMap::getInstance();
    int number = mmp->_myMap[_msg.second];// 在 redis 不存在则返回 0 
    if(!number) { // 不走缓存
        static_cast<WebPageSearcher*>(mode)->doQuery(_msg.second);  
        vector<WebPage> res = static_cast<WebPageSearcher*>(mode)->getQueryWebVec();  
        setRedis(_msg.second, res);
    } 
    else { // 查缓存
        cout << "---------Redis缓存----------" << endl;
        LogInfo("Redis缓存");
        vector<WebPage> res = getRedis(_msg.second, number);
        static_cast<WebPageSearcher*>(mode)->setQueryWebVec(getRedis(_msg.second, number));
    }
    queryResult.first = 2; 
    queryResult.second = static_cast<void*>(static_cast<WebPageSearcher*>(mode)->getQueryWebPtr()); 
}



void MyTask::setRedis(string word, vector<WebPage> &queryResult) {
    auto redis = Redis("tcp://127.0.0.1:6379");
    LogInfo("SetRedis");
    MyMap *mmp = SingleMap::getInstance();
    mmp->_myMap[word] = queryResult.size();

    for(int i = 0; i < queryResult.size(); ++i) {
        string key = word + std::to_string(i);
        json myJson;
        myJson = json{{"title", queryResult[i].title},
            {"link", queryResult[i].link},
            {"description", queryResult[i].description},
            {"content", queryResult[i].content}};
        string jsonString = myJson.dump();
        cout << jsonString << endl;
        redis.set(key, jsonString);
    }
}


vector<WebPage> MyTask::getRedis(string word, int number) {
    auto redis = Redis("tcp://127.0.0.1:6379");
    LogInfo("GetRedis");
    vector<WebPage> res;
    for(int i = 0; i < number; ++i) {
        string key = word + std::to_string(i);
        auto val = redis.get(key);
        json js = json::parse(*val);
        WebPage wp;
        wp.title = js["title"];
        wp.link= js["link"];
        wp.description= js["description"];
        wp.content= js["content"];
        res.push_back(wp);
    }
    return res;
}
